package com.realife.eson.sensor.aop;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

@Slf4j
@Aspect
@Component
public class WebLogAspect {


    @Pointcut("execution(public * com.realife.eson.sensor.controller..*.*(..))")
    public void webLog() {

    }
    

    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Thread thread = Thread.currentThread();
        long threadId = thread.getId();
        String threadName = thread.getName();
        String serialNumber = UUID.randomUUID().toString().replaceAll("-", "");
        Object result = new Object();
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            if (request != null) {
                long begin = System.currentTimeMillis();
                String url = request.getRequestURI();
                String ip = remoteIp(request);
                StringBuilder params = new StringBuilder();
                Signature signature = joinPoint.getSignature();
                MethodSignature methodSignature = (MethodSignature) signature;
                String[] strings = methodSignature.getParameterNames();
                Object[] objects = joinPoint.getArgs();
                for (int i = 0; i < objects.length; i++) {
                    params.append(strings[i] + ":" + objects[i] + ",");
                }
                log.info("=============> 请求开始->serialNumber:{},请求地址:{},请求IP:{} 入参:{}", serialNumber, url, ip, params.toString());
                result = joinPoint.proceed();
                String response = JSONObject.toJSONString(result);
                long end = System.currentTimeMillis();
                log.info("=============> 请求结束->serialNumber:{},出参:{},时间消耗:{}毫秒", serialNumber, response, end - begin);
            }
        } else {
            result = joinPoint.proceed();
        }
        return result;
    }

    public String remoteIp(HttpServletRequest request) {
        if (StringUtils.isNotBlank(request.getHeader("X-Real-IP"))) {
            return request.getHeader("X-Real-IP");
        } else if (StringUtils.isNotBlank(request.getHeader("X-Forwarded-For"))) {
            return request.getHeader("X-Forwarded-For");
        } else if (StringUtils.isNotBlank(request.getHeader("Proxy-Client-IP"))) {
            return request.getHeader("Proxy-Client-IP");
        }
        return request.getRemoteAddr();
    }
}
